///////时钟相关的源码


#include <AHT20.h>
#include <WiFi.h>
#define USE_SERIAL Serial
//#include <_Time.h>
extern void drawScale(String, int, int, int, int, float, float, bool opposition);
extern void setAlarm(int, int);
//tmElements_t tm1;
DateTime nowtime;
char* dayOfWeekName[] = {
  "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"
};
const char* today1 = "";
extern Alarmt alTime;
#include <AHT20.h>
#include <string>
using std::string;
#include <WiFiUdp.h>
WiFiUDP ntpUDP;
#include <NTPClient.h>
// change next line to use with another board/shield
//#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>
NTPClient timeClient(ntpUDP, "ntp.aliyun.com", 60 * 60 * 8, 60000);  //时间（参考ntp获取时间https://blog.csdn.net/veray/article/details/121940328）
const char* ssid = "dht";                                            //账号
const char* password = "12345678";                                   //密码
int Tyear = 0;
int Tmon = 0;
int Tday = 0;
int Thour = 0;
int Tmin = 0;
int Tsec = 0;

#include <HTTPClient.h>
#include <ArduinoJson.h>
int getWeekday(int year, int month, int day) {
  // 计算日期的星期几
  int a = (14 - month) / 12;
  int y = year - a;
  int m = month + 12 * a - 2;
  int d = (day + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12) % 7;

  // 将数字转换成星期几
  switch (d) {
    case 0:
      return 7;  // 周日
      break;
    case 1:
      return 1;  // 周一
      break;
    case 2:
      return 2;  // 周二
      break;
    case 3:
      return 3;  // 周三
      break;
    case 4:
      return 4;  // 周四
      break;
    case 5:
      return 5;  // 周五
      break;
    case 6:
      return 6;  // 周六
      break;
    default:
      return -1;  // 错误
  }
}

void getTwifi() {//联网校时
  String TTime = "";
  connectToWiFi(5, 0);
  // Stream& input;
  if (WiFi.status() == WL_CONNECTED) /*如果有网络就联网*/ {
    HTTPClient http;
    http.begin("http://quan.suning.com/getSysTime.do");  //Specify the URL
    int tryt = 0;
    while (tryt < 3) {
      int httpCode = http.GET();  //Make the request
      if (httpCode > 0) {         //Check for the returning code
        TTime = http.getString();
        Serial.println(httpCode);
        Serial.println(TTime);
        break;
      } else {
        Serial.println("Error on HTTP request");
        tryt++;
      }
    }
    // Stream& input;

    StaticJsonDocument<96> doc;

    DeserializationError error = deserializeJson(doc, TTime);

    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
      return;
    }
    const char* sysTime2 = doc["sysTime2"];  // "2023-09-07 23:32:56"
    const char* sysTime1 = doc["sysTime1"];  // "20230907233256"
    String timeString(sysTime1);

    // 提取年份
    Tyear = atoi(timeString.substring(0, 4).c_str());

    // 提取月份
    Tmon = atoi(timeString.substring(4, 6).c_str());

    // 提取日期
    Tday = atoi(timeString.substring(6, 8).c_str());

    // 提取小时
    Thour = atoi(timeString.substring(8, 10).c_str());

    // 提取分钟
    Tmin = atoi(timeString.substring(10, 12).c_str());

    // 提取秒钟
    Tsec = atoi(timeString.substring(12, 14).c_str());
    // int nyearIndex = TTime.indexOf("nyear=") + 6;
    // int nyearSemicolonIndex = TTime.indexOf(";", nyearIndex);
    // Tyear = TTime.substring(nyearIndex, nyearSemicolonIndex).toInt();

    // int nmonthIndex = TTime.indexOf("nmonth=") + 7;
    // int nmonthSemicolonIndex = TTime.indexOf(";", nmonthIndex);
    // Tmon = TTime.substring(nmonthIndex, nmonthSemicolonIndex).toInt();

    // int ndayIndex = TTime.indexOf("nday=") + 5;
    // int ndaySemicolonIndex = TTime.indexOf(";", ndayIndex);
    // Tday =TTime.substring(ndayIndex, ndaySemicolonIndex).toInt();


    // int nhrsIndex = TTime.indexOf("nhrs=") + 5;
    // int nhrsSemicolonIndex = TTime.indexOf(";", nhrsIndex);
    // Thour = TTime.substring(nhrsIndex, nhrsSemicolonIndex).toInt();

    // int nminIndex = TTime.indexOf("nmin=") + 5;
    // int nminSemicolonIndex = TTime.indexOf(";", nminIndex);
    // Tmin = TTime.substring(nminIndex, nminSemicolonIndex).toInt();

    // int nsecIndex = TTime.indexOf("nsec=") + 5;
    // int nsecSemicolonIndex = TTime.indexOf(";", nsecIndex);
    // Tsec = TTime.substring(nsecIndex, nsecSemicolonIndex).toInt();

    //     Thour=22;
    //     Tmin=20;
    //     Tsec=10;
    // Tyear=23;
    // Tmon=9;
    // Tday=7;
    Serial.println(Tyear);
    Serial.println(Tmon);
    Serial.println(Tday);
    Serial.println(Thour);
    Serial.println(Tmin);
    Serial.println(Tsec);

    SPI.end();
    Wire.begin(8, 7);
    setTime(Thour, Tmin, Tsec, Tday, Tmon, Tyear);
    //RTC.begin();
    RTC.adjust(now());
    //setAlarm(alTime.aMin, alTime.aHour);
    Wire.end();
    SPI.begin(7, 8, 8, 6);
    centerx(TTime, 165, 1, 0, 200, "否");
    nextPage(10, -1);
  }
}
void getT(int& H, int& M, int& S) {//获取本地时间

  SPI.end();
  Wire.begin(8, 7);
  //RTC.begin();
  nowtime = RTC.now();
  //RTC.read(tm1);
  H = nowtime.hour();
  M = nowtime.minute();
  S = nowtime.second();
  Serial.print("Thour");
  Serial.print(H);
  Serial.print("Tmin");
  Serial.print(M);
  Serial.print("Tsec");
  Serial.print(S);
  Serial.print("--------------");
  Serial.print(nowtime.year());
  Serial.print(nowtime.month());
  Serial.print(nowtime.day());
  Serial.println("--------------");
  Wire.end();
  SPI.begin(7, 8, 8, 6);
}

void roundclock() {//指针表盘

  float r1 = 0;
  float r2 = 0;
  int h = 0;

  getT(Thour, Tmin, Tsec);
  float minplus = Tsec / 60;
  float minn = Tmin + minplus;
  float hourplus = minn / 60;
  r1 = minn / 60 * 2 * pi - 0.5 * pi;
  h = (Thour >= 12) ? Thour - 12 : Thour;
  float hourr = Thour + hourplus;
  r2 = hourr / 12 * 2 * pi - 0.5 * pi;
  display.fillScreen(BackC);
  display.drawInvertedBitmap(xshifting, yshifting, roundclockback, 200, 200, FormC);
  Serial.println("today1");
  string today /*星期x*/ = std::__cxx11::to_string(nowtime.month()) + "-" + std::__cxx11::to_string(nowtime.day());  //拼接"星期x"
  today1 = today.c_str();
  Serial.println(today1);
  u8g2Fonts.setFont(u8g2_font_crox5tb_tr);
  centerx(today1, 100, 1, 35, 50);
  today /*星期x*/ = (dayOfWeekName[nowtime.dayOfTheWeek()]);
  today1 = today.c_str();
  Serial.println(today1);
  u8g2Fonts.setFont(u8g2_font_crox5tb_tr);
  centerx(today1, 118, 1, 105, 70);

  drawrotation(minhand, 100, 100, 80, 12, 13, 5, r1);
  drawrotation(hourhand, 100, 100, 64, 10, 15, 5, r2);

  u8g2Fonts.setFontDirection(0);
  u8g2Fonts.setFont(chinese_gb2312);
  nextPage(10, 2);
  //espsleep(1);
}

void digitalclock() {//数字表盘
  //////////////////////////温湿度
  SPI.end();
  Wire.begin(8, 7);
  int temperature = aht20.getTemperature();
  int humidity = aht20.getHumidity();
  u8g2Fonts.setFont(u8g2_font_tenstamps_mf);
  Wire.end();
  //////////////////////////
  getT(Thour, Tmin, Tsec);
  display.fillScreen(BackC);
  display.drawInvertedBitmap(xshifting, yshifting, digitalclockback, 200, 200, FormC);
  centerx((std::__cxx11::to_string(humidity) + "%").c_str(), 45, 1, 138, 50);
  centerx((std::__cxx11::to_string(temperature) + "C").c_str(), 65, 1, 138, 50);
  Serial.println("today1");
  string today /*日期*/ = std::__cxx11::to_string(nowtime.month()) + "-" + std::__cxx11::to_string(nowtime.day());  //拼接"星期x"
  today1 = today.c_str();
  Serial.println(today1);

  u8g2Fonts.setFont(u8g2_font_crox5tb_tr);
  centerx(today1, 140, 1, 1, 98);
  today /*星期x*/ = (dayOfWeekName[nowtime.dayOfTheWeek()]);
  today1 = today.c_str();
  Serial.println(today1);
  centerx(today1, 160, 1, 1, 98);
  //////////////////////////
  u8g2Fonts.setFont(u8g2_font_logisoso50_tf);  //u8g2_font_inb63_mn
  u8g2Fonts.setForegroundColor(BackC);
  u8g2Fonts.setBackgroundColor(FormC);
  Serial.print("Thour");
  Serial.println(Thour);
  string timeh = (Thour < 10) ? ("0" + std::__cxx11::to_string(Thour)) : (std::__cxx11::to_string(Thour));
  string timem = (Tmin < 10) ? ("0" + std::__cxx11::to_string(Tmin)).c_str() : (std::__cxx11::to_string(Tmin)).c_str();
  u8g2Fonts.setCursor(20, 80 + yshifting);  //文本居中
  u8g2Fonts.print(timeh.c_str());
  Serial.print("timeh");
  Serial.println(timeh.c_str());
  u8g2Fonts.setCursor(105, 170 + yshifting);  //文本居中
  u8g2Fonts.print(timem.c_str());
  nextPage(10, 1);
  //espsleep(1);
  u8g2Fonts.setFont(chinese_gb2312);
}

void selfclock() {//自定义表盘
  getT(Thour, Tmin, Tsec);
  display.fillScreen(BackC);
  picfile = FFat.open("/[p]clockpic.p", FILE_READ);
  picout = picfile.readString();
  picfile.close();
  drawScale(picout, 0, 0, 200, 200, 1, 1, false);
  u8g2Fonts.setFont(u8g2_font_logisoso50_tf);
  u8g2Fonts.setForegroundColor(FormC);  // 设置前景色
  u8g2Fonts.setBackgroundColor(BackC);  // 设置背景色
  string timeh = (Thour < 10) ? ("0" + std::__cxx11::to_string(Thour)) : (std::__cxx11::to_string(Thour));
  string timem = (Tmin < 10) ? ("0" + std::__cxx11::to_string(Tmin)).c_str() : (std::__cxx11::to_string(Tmin)).c_str();
  string x = timeh + ":" + timem;  //拼凑出离线时间
  const char* text = x.c_str();    //string转char才能被输出在屏幕
  switch(clocklocation){
    case 0:display.fillRoundRect(29,10,142,60,10,BackC);centerx(text, 60); break;
    case 1:display.fillRoundRect(29,70,142,60,10,BackC);centerx(text, 120); break;
    case 2:display.fillRoundRect(29,125,142,60,10,BackC);centerx(text, 180); break;
  }
  u8g2Fonts.setFont(chinese_gb2312);
  display.nextPage();
}


void clockloop(int clockmod = 0,int displaymod=0) {//时钟主界面（循环）
  
  bool ledmod = false;
  display.firstPage();
  //centerx("校时" 125,, 1, 0, 200, "否");
  //nextPage(10);
  esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
  gpio_wakeup_enable(GPIO_NUM_18, GPIO_INTR_LOW_LEVEL);
  gpio_wakeup_enable(GPIO_NUM_19, GPIO_INTR_LOW_LEVEL);
  gpio_wakeup_enable(GPIO_NUM_9, GPIO_INTR_LOW_LEVEL);
  gpio_wakeup_enable(GPIO_NUM_4, GPIO_INTR_ANYEDGE);
  gpio_wakeup_enable(GPIO_NUM_4, GPIO_INTR_LOW_LEVEL);
  gpio_wakeup_enable(GPIO_NUM_4, GPIO_INTR_NEGEDGE);
  esp_sleep_enable_gpio_wakeup();
  while (1) {
    switch (clockmod) {
      case 0: roundclock(); break;
      case 1: digitalclock(); break;
      case 2: selfclock(); break;
      default: digitalclock(); break;
    }

    esp_sleep_enable_timer_wakeup(1 * 60 * 1000000);
    Serial.println("Sleep");
    esp_light_sleep_start();
    if(displaymod!=0&&esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TIMER)break;
    //display.nextPage();
    SPI.end();
    Wire.begin(8, 7);
    isAlarmedcheck();
    Wire.end();
    SPI.begin(7, 8, 8, 6);

    //if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TIMER){ display.fillScreen(FormC);display.nextPage();continue;}
    if (tapcheck(1)) {
      delay(200);
      if (tapcheck(1)) {
        clockmod = (clockmod == 2) ? 0 : clockmod + 1;
      } else themechange();
    }
    if (tapcheck(3)) {
      if (!ledmod) {
        digitalWrite(lightpin, HIGH);
        ledmod = true;
      } else if (ledmod) {
        digitalWrite(lightpin, LOW);
        ledmod = false;
      }
    }
    if (tapcheck(2)) break;
  }
  esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
}

void timeconfig() {//校时主界面
  display.firstPage();
  display.fillScreen(BackC);
  int timeset[4] = { 0, 0, 0, 0 };
  display.drawInvertedBitmap(xshifting, yshifting, alarmback, 200, 200, FormC);
  u8g2Fonts.setForegroundColor(FormC);
  u8g2Fonts.setBackgroundColor(BackC);
  u8g2Fonts.setFont(chinese_gb2312);
  u8g2Fonts.setCursor(20 + xshifting, 172 + yshifting);
  u8g2Fonts.print("切换/调时");
  u8g2Fonts.setCursor(155 + xshifting, 172 + yshifting);
  u8g2Fonts.print("设定");
  u8g2Fonts.setCursor(155 + xshifting, 25 + yshifting);
  u8g2Fonts.print("退出");
  u8g2Fonts.setForegroundColor(BackC);
  u8g2Fonts.setBackgroundColor(FormC);
  u8g2Fonts.setFont(u8g2_font_logisoso50_tf);
  u8g2Fonts.setCursor(12 + xshifting, 125 + yshifting);
  u8g2Fonts.print(timeset[0]);
  u8g2Fonts.setCursor(56 + xshifting, 125 + yshifting);
  u8g2Fonts.print(timeset[1]);
  u8g2Fonts.setCursor(112 + xshifting, 125 + yshifting);
  u8g2Fonts.print(timeset[2]);
  u8g2Fonts.setCursor(156 + xshifting, 125 + yshifting);
  u8g2Fonts.print(timeset[3]);
  display.drawRoundRect(16 + xshifting, 124 + yshifting, 22, 4, 5, BackC);
  nextPage(10, 2);
  u8g2Fonts.setFont(chinese_gb2312);
  int timechoice = 0;

  while (1) {
    espsleep(1);
    if (tapcheck(1)) {
      delay(300);
      display.firstPage();
      display.fillScreen(BackC);
      display.drawInvertedBitmap(xshifting, yshifting, alarmback, 200, 200, FormC);
      if (tapcheck(1)) {
        timechoice = (timechoice == 3) ? 0 : timechoice + 1;
        if (timechoice == 0) {
          display.drawRoundRect(10 + 16 + xshifting + 3 * 46, 124 + yshifting, 22, 4, 5, FormC);
          display.drawRoundRect(16 + xshifting + timechoice * 46, 124 + yshifting, 22, 4, 5, BackC);
        } else if (timechoice == 2) {
          display.drawRoundRect(16 + xshifting + (timechoice - 1) * 46, 124 + yshifting, 22, 4, 5, FormC);
          display.drawRoundRect(10 + 16 + xshifting + timechoice * 46, 124 + yshifting, 22, 4, 5, BackC);
        } else if (timechoice == 3) {
          display.drawRoundRect(10 + 16 + xshifting + (timechoice - 1) * 46, 124 + yshifting, 22, 4, 5, FormC);
          display.drawRoundRect(10 + 16 + xshifting + timechoice * 46, 124 + yshifting, 22, 4, 5, BackC);
        } else {
          display.drawRoundRect(16 + xshifting + (timechoice - 1) * 46, 124 + yshifting, 22, 4, 5, FormC);
          display.drawRoundRect(16 + xshifting + timechoice * 46, 124 + yshifting, 22, 4, 5, BackC);
        }

      } else {
        if (timechoice == 0) timeset[timechoice] = (timeset[timechoice] == 2) ? 0 : timeset[timechoice] + 1;
        else if (timechoice == 2) timeset[timechoice] = (timeset[timechoice] == 5) ? 0 : timeset[timechoice] + 1;
        else timeset[timechoice] = (timeset[timechoice] == 9) ? 0 : timeset[timechoice] + 1;
      }
      u8g2Fonts.setForegroundColor(FormC);
      u8g2Fonts.setBackgroundColor(BackC);
      u8g2Fonts.setFont(chinese_gb2312);
      u8g2Fonts.setCursor(20 + xshifting, 172 + yshifting);
      u8g2Fonts.print("切换/调时");
      u8g2Fonts.setCursor(155 + xshifting, 172 + yshifting);
      u8g2Fonts.print("设定");
      u8g2Fonts.setCursor(155 + xshifting, 25 + yshifting);
      u8g2Fonts.print("退出");
      u8g2Fonts.setForegroundColor(BackC);
      u8g2Fonts.setBackgroundColor(FormC);
      u8g2Fonts.setFont(u8g2_font_logisoso50_tf);
      u8g2Fonts.setForegroundColor(BackC);
      u8g2Fonts.setBackgroundColor(FormC);
      u8g2Fonts.setCursor(12 + xshifting, 125 + yshifting);
      u8g2Fonts.print(timeset[0]);
      u8g2Fonts.setCursor(56 + xshifting, 125 + yshifting);
      u8g2Fonts.print(timeset[1]);
      u8g2Fonts.setCursor(112 + xshifting, 125 + yshifting);
      u8g2Fonts.print(timeset[2]);
      u8g2Fonts.setCursor(156 + xshifting, 125 + yshifting);
      u8g2Fonts.print(timeset[3]);
      nextPage(10, 2);
    }
    if (tapcheck(2)) {
      return;
    }
    if (tapcheck(3)) {
      int setH = timeset[0] * 10 + timeset[1];
      int setM = timeset[2] * 10 + timeset[3];
      centerx("已设置", 80, 1, 0, 200, "否");
      nextPage();
      SPI.end();
      Wire.begin(8, 7);
      setTime(setH, setM, 0, 1, 10, 23);
      RTC.adjust(now());
      Wire.end();
      SPI.begin(7, 8, 8, 6);
      return;
    }
  }
}



void configtimedesk() {
  display.firstPage();
  display.fillScreen(BackC);
  display.drawInvertedBitmap(xshifting, yshifting, configtimeback, 200, 200, FormC);
  nextPage();
  while (1) {
    espsleep();
    if (tapcheck(1)) {
      getTwifi();
      display.firstPage();
      display.fillScreen(BackC);
      drawScale(settingicon, 68, 48, 64, 64, 1, 1, false);
      centerx("校时中...", 125, 1, 0, 200, "否");
      nextPage(10, -1);
      return;
    }
    if (tapcheck(2)) return;
    if (tapcheck(3)) timeconfig();
    return;
  }
}